package com.handydata.antifraud.service.impl;

import com.alibaba.fastjson.JSON;
import com.handydata.antifraud.bo.alarmruledef.AlarmRuleDefBeanBO;
import com.handydata.antifraud.bo.alarmruledef.AlarmRuleDefReqBO;
import com.handydata.antifraud.bo.alarmruledef.AlarmRuleDefResBO;
import com.handydata.antifraud.bo.dictinfo.DictInfoReqBO;
import com.handydata.antifraud.bo.dictinfo.DictInfoResBO;
import com.handydata.antifraud.common.constant.AlarmInfoCode;
import com.handydata.antifraud.common.constant.DictInfoCode;
import com.handydata.antifraud.common.exception.AlarmRuleDefExCode;
import com.handydata.antifraud.dao.AlarmRuleDefDao;
import com.handydata.antifraud.entity.AlarmRuleDefDO;
import com.handydata.antifraud.service.AlarmRuleDefService;
import com.handydata.antifraud.service.DictInfoService;
import com.handydata.common.convert.CommonBeanConvertor;
import com.handydata.common.exception.SysException;
import com.handydata.common.service.AbsService;
import com.handydata.common.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service("alarmRuleDefService")
public class AlarmRuleDefServiceImpl extends AbsService implements AlarmRuleDefService {
	
	private static final Logger logger = LoggerFactory.getLogger(AlarmRuleDefServiceImpl.class);
	
	@Autowired
	private AlarmRuleDefDao alarmRuleDefDao;

	@Autowired
	DictInfoService dictInfoService;

	@Autowired
	RedisUtil redisUtil;

	@Transactional
	@Override
	public AlarmRuleDefResBO createAlarmRuleDef(AlarmRuleDefReqBO req) throws SysException{

	    AlarmRuleDefResBO res = new AlarmRuleDefResBO();
		try {
			AlarmRuleDefDO entity = CommonBeanConvertor.convert(req, AlarmRuleDefDO.class);
			entity.setId(UUID.randomUUID().toString().replace("-", ""));
			entity.setCreateTime(Calendar.getInstance().getTime());
			long status = alarmRuleDefDao.insert(entity);
			if(status == 0) {
				res.setExCode(AlarmRuleDefExCode.SYS_NO_ENTITY_CREATED);
			} else {
				res.setExCode(AlarmRuleDefExCode.SUCCESS);
			}

		} catch (Exception e) {
			logger.error("Create new entity {} get into error", req, e);
			throw new SysException(AlarmRuleDefExCode.SYS_CREATE_ENTITY_ERROR);
		}
		
		return res;
	}

	private String getRuleRedisKey(String alertItem,String wsCode,String productCode){
		String key= alertItem+"_";
		if(wsCode!=null&&wsCode.length()>0){
			key+=wsCode;
		}else{
			key+=productCode;
		}
		return key;
	}
	@Transactional
	@Override
	public AlarmRuleDefResBO modifyAlarmRuleDef(AlarmRuleDefReqBO req) throws SysException{
	    AlarmRuleDefResBO res = new AlarmRuleDefResBO();
		try {
			AlarmRuleDefDO condition = CommonBeanConvertor.convert(req, AlarmRuleDefDO.class);
			long status = alarmRuleDefDao.update(condition);
			if(status == 0) {
				res.setExCode(AlarmRuleDefExCode.SYS_NO_ENTITY_MODIFIED);
			} else {
				res.setExCode(AlarmRuleDefExCode.SUCCESS);
				String key=getRuleRedisKey(condition.getAlertItem(),condition.getWsCode(),condition.getProductCode());
				redisUtil.set(AlarmInfoCode.REDIS_ALARM_RULE_ALL.getCode()+"_"+key,JSON.toJSON(condition).toString());
				redisUtil.set(AlarmInfoCode.REDIS_ALARM_RULE_TIMEOUT.getCode()+"_"+key,condition.getTimeout());
			}
		} catch (Exception e) {
			logger.error("Modify entity {} get into error", req, e);
			throw new SysException(AlarmRuleDefExCode.SYS_MODIFY_ENTITY_ERROR);
		} 
		return res;
	}

	@Transactional
	@Override
	public AlarmRuleDefResBO deleteAlarmRuleDef(AlarmRuleDefReqBO req) throws SysException{
	    AlarmRuleDefResBO res = new AlarmRuleDefResBO();
		
		try {
			AlarmRuleDefDO condition = CommonBeanConvertor.convert(req, AlarmRuleDefDO.class);
			long status = alarmRuleDefDao.delete(condition);
			if(status == 0) {
				res.setExCode(AlarmRuleDefExCode.SYS_NO_ENTITY_DELETED);
			} else {
				res.setExCode(AlarmRuleDefExCode.SUCCESS);
			}

			String key=getRuleRedisKey(condition.getAlertItem(), condition.getWsCode(),condition.getProductCode());
			redisUtil.del(AlarmInfoCode.REDIS_ALARM_RULE_ALL.getCode()+"_"+key);
			redisUtil.del(AlarmInfoCode.REDIS_ALARM_RULE_TIMEOUT.getCode()+"_"+key);
		} catch (Exception e) {
			logger.error("Delete entity {} get into error", req, e);
			throw new SysException(AlarmRuleDefExCode.SYS_DELETE_ENTITY_ERROR);
		}
		return res;
	}

	@Override
	public AlarmRuleDefResBO queryAlarmRuleDef(AlarmRuleDefReqBO req) throws SysException{
		AlarmRuleDefDO condition = CommonBeanConvertor.convert(req, AlarmRuleDefDO.class);
		AlarmRuleDefResBO res;
		
		try {
			int start=(req.getPageNumber()-1)*req.getPageSize();
			long count=alarmRuleDefDao.count(condition);
			List<AlarmRuleDefDO> entities = alarmRuleDefDao.query(condition,start,start+req.getPageSize());//,req.g
			res = CommonBeanConvertor.convert(entities, AlarmRuleDefResBO.class, AlarmRuleDefBeanBO.class);


			if(res.getEarlyWarnSetList()!=null&&res.getEarlyWarnSetList().size()>0){

				DictInfoReqBO bo=new DictInfoReqBO();
				bo.setType(DictInfoCode.DICT_PRODUCT.getCode());
				DictInfoResBO resBo=dictInfoService.queryDictInfo(bo);

				Map<String,String> dictMap=new HashMap<>();
				if(resBo.getResultList()!=null&&resBo.getResultList().size()>0){
					resBo.getResultList().forEach((x) -> {
						dictMap.put(x.getCode(),x.getName());
					});
				}
				res.getEarlyWarnSetList().forEach((x) -> {
					x.setSendModeName(AlarmInfoCode.sendModelMap.get(x.getSendMode()));
					x.setAlertTypeName(AlarmInfoCode.alertTypeMap.get(x.getAlertType()));
					x.setAlertItemName(AlarmInfoCode.alertItemMap.get(x.getAlertItem()));
					x.setProductName(dictMap.get(x.getProductCode()));

				});
			}
			res.setTotalNumber(count);
			double c1=count;
			double c2=req.getPageSize();

			res.setTotalPage(Double.valueOf(Math.ceil(c1/c2)).intValue());
			res.setExCode(AlarmRuleDefExCode.SUCCESS);
		} catch(Exception e) {
			logger.error("Query entity {} get into error", req, e);
			throw new SysException(AlarmRuleDefExCode.SYS_QUERY_ENTITY_ERROR);
		}
		return res;
	}


	@Override
	public void loadAlarmRuleToCache() throws SysException{
		logger.info("开始加载预警规则配置到redis");
		AlarmRuleDefDO condition = new AlarmRuleDefDO();
		try {
			List<AlarmRuleDefDO> entities = alarmRuleDefDao.query(condition);//,req.g

			if(entities!=null&&entities.size()>0){
				for(AlarmRuleDefDO x:entities){
					if(x==null||x.getTimeout()==null||x.getReceiveByMail()==null){
						logger.warn("该预警规则定义不全，可能导致无法预警,{}",x.getId());
					}else{
						String key=getRuleRedisKey(x.getAlertItem(),x.getWsCode(),x.getProductCode());
						redisUtil.set(AlarmInfoCode.REDIS_ALARM_RULE_ALL.getCode()+"_"+key,JSON.toJSON(x).toString());
						redisUtil.set(AlarmInfoCode.REDIS_ALARM_RULE_TIMEOUT.getCode()+"_"+key,x.getTimeout());
					}
				}

				logger.info("成功加载"+entities.size()+"条预警规则到reids");

			}else{
				logger.warn("警告，系统还没设置预警规则，可能导致无法预警");

			}
		} catch(Exception e) {
			logger.error("load warn rule entity to redis get into error", e);
			throw new SysException(AlarmRuleDefExCode.SYS_LOAD_RULETO_REDIS);
		}
	}

}
